return 0;
}
+
+unsigned int acpi_get_processor_id(unsigned int cpu)
+{
+ unsigned int acpiid, apicid;
+
+ if ((apicid = x86_cpu_to_apicid[cpu]) == 0xff)
+ return 0xff;
+
+ for (acpiid = 0; acpiid < ARRAY_SIZE(x86_acpiid_to_apicid); acpiid++)
+ if (x86_acpiid_to_apicid[acpiid] == apicid)
+ return acpiid;
+
+ return 0xff;
+}
#include <xen/console.h>
#include <xen/percpu.h>
#include <xen/compat.h>
+#include <xen/acpi.h>
#include <asm/regs.h>
#include <asm/mc146818rtc.h>
#include <asm/system.h>
break;
}
+ case VCPUOP_get_physid:
+ {
+ struct vcpu_get_physid cpu_id;
+
+ rc = -EINVAL;
+ if ( !v->domain->is_pinned )
+ break;
+
+ cpu_id.phys_id = (x86_cpu_to_apicid[v->vcpu_id] |
+ (acpi_get_processor_id(v->vcpu_id) << 8));
+
+ rc = -EFAULT;
+ if ( copy_to_guest(arg, &cpu_id, 1) )
+ break;
+
+ rc = 0;
+ break;
+ }
+
default:
rc = -ENOSYS;
break;
#include <public/vcpu.h>
#include <xsm/xsm.h>
+/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
+static unsigned int opt_dom0_vcpus_pin;
+boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
+
+enum cpufreq_controller cpufreq_controller;
+static void __init setup_cpufreq_option(char *str)
+{
+ if ( !strcmp(str, "dom0-kernel") )
+ {
+ cpufreq_controller = FREQCTL_dom0_kernel;
+ opt_dom0_vcpus_pin = 1;
+ }
+}
+custom_param("cpufreq", setup_cpufreq_option);
+
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
DEFINE_RCU_READ_LOCK(domlist_read_lock);
if ( domcr_flags & DOMCRF_hvm )
d->is_hvm = 1;
+ if ( (domid == 0) && opt_dom0_vcpus_pin )
+ d->is_pinned = 1;
+
rangeset_domain_initialise(d);
if ( !is_idle_domain(d) )
static char opt_sched[10] = "credit";
string_param("sched", opt_sched);
-/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
-static unsigned int opt_dom0_vcpus_pin;
-boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
-
-enum cpufreq_controller cpufreq_controller;
-static void __init setup_cpufreq_option(char *str)
-{
- if ( !strcmp(str, "dom0-kernel") )
- {
- cpufreq_controller = FREQCTL_dom0_kernel;
- opt_dom0_vcpus_pin = 1;
- }
-}
-custom_param("cpufreq", setup_cpufreq_option);
-
#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */
/* Various timer handlers. */
* domain-0 VCPUs, are pinned onto their respective physical CPUs.
*/
v->processor = processor;
- if ( is_idle_domain(d) || ((d->domain_id == 0) && opt_dom0_vcpus_pin) )
+ if ( is_idle_domain(d) || d->is_pinned )
v->cpu_affinity = cpumask_of_cpu(processor);
else
cpus_setall(v->cpu_affinity);
int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
{
- if ( (v->domain->domain_id == 0) && opt_dom0_vcpus_pin )
+ if ( v->domain->is_pinned )
return -EINVAL;
return __vcpu_set_affinity(v, affinity, 0, 0);
}
*
* This may be called only once per vcpu.
*/
-#define VCPUOP_register_vcpu_info 10 /* arg == struct vcpu_info */
+#define VCPUOP_register_vcpu_info 10 /* arg == vcpu_register_vcpu_info_t */
struct vcpu_register_vcpu_info {
uint64_t mfn; /* mfn of page to place vcpu_info */
uint32_t offset; /* offset within page */
/* Send an NMI to the specified VCPU. @extra_arg == NULL. */
#define VCPUOP_send_nmi 11
+/*
+ * Get the physical ID information for a pinned vcpu's underlying physical
+ * processor. The physical ID informmation is architecture-specific.
+ * On x86: id[7:0]=apic_id, id[15:8]=acpi_id, id[63:16]=mbz,
+ * and an unavailable identifier is returned as 0xff.
+ * This command returns -EINVAL if it is not a valid operation for this VCPU.
+ */
+#define VCPUOP_get_physid 12 /* arg == vcpu_get_physid_t */
+struct vcpu_get_physid {
+ uint64_t phys_id;
+};
+typedef struct vcpu_get_physid vcpu_get_physid_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
+#define xen_vcpu_physid_to_x86_apicid(physid) ((uint8_t)((physid)>>0))
+#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint8_t)((physid)>>8))
+
#endif /* __XEN_PUBLIC_VCPU_H__ */
/*
typedef int (*acpi_madt_entry_handler) (acpi_table_entry_header *header, const unsigned long end);
+unsigned int acpi_get_processor_id (unsigned int cpu);
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
unsigned long acpi_find_rsdp (void);
int acpi_boot_init (void);
enum { DOMDYING_alive, DOMDYING_dying, DOMDYING_dead } is_dying;
/* Domain is paused by controller software? */
bool_t is_paused_by_controller;
+ /* Domain's VCPUs are pinned 1:1 to physical CPUs? */
+ bool_t is_pinned;
/* Guest has shut down (inc. reason code)? */
spinlock_t shutdown_lock;